#include "SignalHandler.h"


SignalHandler SignalHandler :: instance;
EventHandler* SignalHandler :: signal_handlers [ NSIG ];

SignalHandler :: SignalHandler () {
}

SignalHandler& SignalHandler :: getInstance () {

	return instance;
}

int SignalHandler :: emitirSenial(int pid, int signum)
{
	return kill(pid,signum);
}


void SignalHandler :: bloquearSenial(int signum)
{
	sigset_t sa;
	sigemptyset ( &sa );
	sigaddset ( &sa,signum );
	sigprocmask ( SIG_BLOCK,&sa,NULL );
}


void SignalHandler :: desbloquearSenial(int signum)
{

	sigset_t sa;
	sigemptyset ( &sa );
	sigaddset ( &sa,signum );
	sigprocmask ( SIG_UNBLOCK,&sa,NULL );
}

void SignalHandler :: desbloquearTodasSeniales()
{
	sigset_t sa;
	sigfillset ( &sa );
	sigprocmask ( SIG_UNBLOCK,&sa,NULL );
}

void SignalHandler :: bloquearTodasSeniales()
{
	sigset_t sa;
	sigfillset ( &sa );
	sigprocmask ( SIG_BLOCK,&sa,NULL );
}

EventHandler* SignalHandler :: registrarHandler ( int signum,EventHandler* eh ) {

	EventHandler* old_eh = SignalHandler :: signal_handlers [ signum ];
	SignalHandler :: signal_handlers [ signum ] = eh;

	struct sigaction sa;
	sa.sa_handler = SignalHandler :: dispatcher;
	sigemptyset ( &sa.sa_mask );	// inicializa la mascara de seniales a bloquear durante la ejecucion del handler como vacio
	sa.sa_flags = 0;
	sigaction ( signum,&sa,0 );	// cambiar accion de la senial

	return old_eh;
}

void SignalHandler :: dispatcher ( int signum ) {

	if ( SignalHandler :: signal_handlers [ signum ] != 0 )
		SignalHandler :: signal_handlers [ signum ]->handleSignal ( signum );
}

int SignalHandler :: removerHandler ( int signum ) {

	SignalHandler :: signal_handlers [ signum ] = NULL;
	return 0;
}

EventHandler*  SignalHandler :: getHandler( int signum ) {

	EventHandler *handler = NULL;

	if(signum < NSIG)
		handler = signal_handlers[signum];
	return handler;
}

